home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 06 - 1990 / 06.12 Dec 90 / dissMask Source / main.c < prev   
Encoding:
C/C++ Source or Header  |  1990-08-23  |  5.9 KB  |  198 lines  |  [TEXT/KAHL]

  1. /*    Quick and dirty demo application for dissMask routines.
  2.         Written August 1990 by Mike Morton for MacTutor.
  3. */
  4. #include "dissMask.h"
  5.  
  6. /*    “dissolve” is just a part of the driver; you’ll probably want
  7.         your own code to call the dissMask____ functions(), although
  8.         your code will look a lot like “dissolve”. */
  9. static void dissolve (BitMap *srcBits, BitMap *dstBits, Rect *srcRect,
  10.                                             Rect *dstRect, unsigned short steps);
  11.  
  12. void main (void)
  13. {    Rect winBounds;
  14.     WindowRecord theWindow;
  15.     Handle scrapHandle;
  16.     long scrapResult;
  17.     long scrapOffset;
  18.     char windowTitle [100];
  19.     BitMap offScreen, winBits;
  20.     short rows, cols;
  21.     EventRecord evt;
  22.     long dummy;
  23.     short clipCopies, clipCount;
  24.     PicHandle thePict;
  25.     short picWidth, picHeight;
  26.     Rect target;
  27.  
  28.     /*    Standard Mac init, skipping menus & TE & dialogs: */
  29.     InitGraf (& thePort);
  30.     InitFonts ();
  31.     FlushEvents (everyEvent, 0);
  32.     InitWindows ();
  33.     InitCursor ();
  34.  
  35.     /*    We prefer to be run with graphics on the clipboard,
  36.             but protest only feebly if there’s no PICT: */
  37.     strcpy (windowTitle, "Dissolve demo using CopyMask");
  38.     scrapHandle = NewHandle (0L);
  39.     scrapResult = GetScrap (scrapHandle, 'PICT', & scrapOffset);
  40.     if (scrapResult < 0) /* no PICT available? */
  41.         strcat (windowTitle, " (NO PICTURE ON CLIPBOARD)");
  42.     CtoPstr (windowTitle);
  43.  
  44.     /*    Steal the main screen, inset a bit, and avoid the menu bar. */
  45.     winBounds = screenBits.bounds;
  46.     InsetRect (& winBounds, 8, 8);
  47.     winBounds.top += 20 + MBarHeight;
  48.  
  49.     /*    Make up a new window: */
  50.     NewWindow (& theWindow, & winBounds, windowTitle,
  51.         true, /*visible at first*/ noGrowDocProc,
  52.         -1L, /*frontmost*/ false, /*no go-away box*/
  53.         0L); /*no refcon*/
  54.     SetPort ((GrafPtr) & theWindow);
  55.     winBits = thePort->portBits; /* remember where onscreen bit image is */
  56.  
  57.     rows = thePort->portRect.bottom - thePort->portRect.top;
  58.     cols = thePort->portRect.right - thePort->portRect.left;
  59.  
  60.     /*    Make up a bitmap with the same bounds as the window. */
  61.     offScreen.bounds = thePort->portRect;
  62.     offScreen.rowBytes = (cols + 7) / 8;
  63.     if (offScreen.rowBytes & 1)
  64.         ++offScreen.rowBytes;
  65.     offScreen.baseAddr =
  66.         NewPtrClear (rows * (long) offScreen.rowBytes);
  67.     if (offScreen.baseAddr == 0) /* out of memory? */
  68.     {    SysBeep (10); /* be uninformative */
  69.         ExitToShell ();
  70.     }
  71.  
  72.     /*    Fill up the offscreen bitmap.  If we have a clipboard PICT, tile
  73.             the offscreen bitmap with it; else fill the bitmap with black. */
  74.     SetPortBits (& offScreen);
  75.     if (scrapResult >= 0)
  76.     {    thePict = (PicHandle) scrapHandle;
  77.         target = (**thePict).picFrame;
  78.         picWidth = target.right - target.left;
  79.         picHeight = target.bottom - target.top;
  80.  
  81.         /*    Tile the offscreen image with copies of the PICT. */
  82.         clipCopies = 0;
  83.         target.top = 0;
  84.         target.bottom = picHeight;
  85.         while (target.top < thePort->portRect.bottom)
  86.         {    target.left = 0;
  87.             target.right = picWidth;
  88.             while (target.left < thePort->portRect.right)
  89.             {    DrawPicture (thePict, & target);
  90.                 OffsetRect (& target, picWidth, 0);
  91.                 ++clipCopies;
  92.             }
  93.             OffsetRect (& target, 0, picHeight);
  94.         }
  95.  
  96.     }
  97.     else /* no PICT? */
  98.         FillRect (& thePort->portRect, black); /* paint it black, you devil */
  99.     SetPortBits (& winBits);
  100.  
  101.     /*    Bring in ALL this to show the speed of a nearly-full-screen dissolve. */
  102.     dissolve (& offScreen, & theWindow.port.portBits,
  103.                             & thePort->portRect, & thePort->portRect, 10);
  104.     Delay (60L, & dummy);
  105.     EraseRect (& thePort->portRect);
  106.  
  107.     /*    If we have a clipboard PICT, dissolve these things in at
  108.             varying speeds -- note the last parameter to dissolve(). */
  109.     if (scrapResult >= 0)
  110.     {    clipCount = 1;
  111.         target.top = 0;
  112.         target.bottom = picHeight;
  113.         while (target.top < thePort->portRect.bottom)
  114.         {    target.left = 0;
  115.             target.right = picWidth;
  116.             while (target.left < thePort->portRect.right)
  117.             {    /*    The first image dissolves in 20 steps; the last
  118.                         one in fewer. */
  119.                 dissolve (& offScreen, & theWindow.port.portBits,
  120.                                     & target, & target,
  121.                                     20 * (clipCopies - clipCount) / clipCopies);
  122.                 OffsetRect (& target, picWidth, 0);
  123.                 ++clipCount;
  124.             }
  125.             OffsetRect (& target, 0, picHeight);
  126.         }
  127.         Delay (60L, & dummy);
  128.         EraseRect (& thePort->portRect);
  129.     }
  130.  
  131.     /*    Let ’em draw selections to be dissolved in. */
  132.     SetWTitle (& theWindow, "\pClick and drag to dissolve … press a key to exit");
  133.     do
  134.     {    GetNextEvent (everyEvent, & evt);
  135.         if (evt.what == mouseDown)
  136.         {    GlobalToLocal (& evt.where);
  137.             if (PtInRect (evt.where, & thePort->portRect))
  138.             {    Point startPt, endPt, curPt;
  139.                 Rect frame;
  140.  
  141.                 PenPat (gray); PenSize (1, 1); PenMode (patXor);
  142.                 startPt = evt.where;
  143.                 endPt = evt.where;
  144.                 Pt2Rect (startPt, endPt, & frame);
  145.                 FrameRect (& frame);
  146.                 while (StillDown ())
  147.                 {    GetMouse (& curPt);
  148.                     if (curPt.v < 0) curPt.v = 0; /* hack to avoid mysterious bugs */
  149.                     if (! EqualPt (curPt, endPt))
  150.                     {    FrameRect (& frame);
  151.                         endPt = curPt;
  152.                         Pt2Rect (startPt, endPt, & frame);
  153.                         FrameRect (& frame);
  154.                     }
  155.                 }
  156.                 FrameRect (& frame);
  157.                 dissolve (& offScreen, & theWindow.port.portBits,
  158.                                         & frame, & frame, 20);
  159.  
  160.             }
  161.             else SysBeep (2); /* click outside window */
  162.         } /* end of handling mousedown */
  163.     } while (evt.what != keyDown);
  164.  
  165. } /* end of main () */
  166.  
  167. /*    dissolve -- A quick driver for dissMask routines.  It sets up
  168.         the dissolve and does it in the specified number of iterations. */
  169. static void dissolve (srcBits, dstBits, srcRect, dstRect, steps)
  170.     BitMap *srcBits, *dstBits;
  171.     Rect *srcRect, *dstRect;
  172.     unsigned short steps;
  173. {    dissMaskInfo info;
  174.     unsigned long pixPerStep;
  175.  
  176.     /*    Initialize for the dissolve; if it fails, just copy outright: */
  177.     if (! dissMaskInit (srcRect, & info))
  178.     {    CopyBits (srcBits, dstBits, srcRect, dstRect, srcCopy, 0L);
  179.         return;
  180.     }
  181.  
  182.     if (steps == 0) steps = 1;
  183.     pixPerStep = (info.pixLeft / steps) + 1;
  184.  
  185.     /*    Main dissolve loop: repeatedly darken the mask
  186.             bitmap and CopyMask through it. */
  187.     HideCursor ();
  188.     while (info.pixLeft)
  189.     {    dissMaskNext (& info, pixPerStep);
  190.         CopyMask (srcBits, & info.maskMap, dstBits,
  191.                             srcRect, & info.maskRect, dstRect);
  192.     }
  193.  
  194.     /*    Clean up: */
  195.     ShowCursor ();
  196.     dissMaskFinish (& info);
  197. } /* end of dissolve () */
  198.